package com.crm.service.system.department.service.imppl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.crm.model.common.dtos.PageResult;
import com.crm.model.common.dtos.ResponseResult;
import com.crm.model.common.enums.AppHttpCodeEnum;
import com.crm.model.system.department.dtos.DepartmentDto;
import com.crm.model.system.department.dtos.DepartmentPageDto;
import com.crm.model.system.department.pojos.Department;
import com.crm.model.system.department.vo.DepartmentNameVo;
import com.crm.model.system.department.vo.DepartmentPageVo;
import com.crm.service.system.department.mapper.DepartmentMapper;
import com.crm.service.system.department.service.DepartmentService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements DepartmentService {
    @Autowired
    private DepartmentMapper departmentMapper;

    /**
     * 部门分页查询
     *
     * @param departmentPageDto
     * @return
     */
    @Override
    public ResponseResult pageList(DepartmentPageDto departmentPageDto) {
//        参数校验
        if (departmentPageDto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
//        页码或页数为空
        if (departmentPageDto.getPage() == null || departmentPageDto.getPageSize() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PAGE_PAGESIZE_IS_EMPTY);
        }
//        分页查询
        PageHelper.startPage(departmentPageDto.getPage(), departmentPageDto.getPageSize());
        List<DepartmentPageVo> departments = departmentMapper.pageList(departmentPageDto);
        PageInfo pageInfo = new PageInfo(departments);
//        树化结果
        List<DepartmentPageVo> tree = tree(departments);
        PageResult pageResult = new PageResult();
        pageResult.setRecords(tree);
        pageResult.setTotal(pageInfo.getTotal());
        return ResponseResult.okResult(pageResult);

    }

    /**
     * 部门名称列表
     *
     * @return
     */
    @Override
    public ResponseResult namelist() {
//        查询名称列表
        List<DepartmentNameVo> departmentNameVos = departmentMapper.nameList();
//        树化
        List<DepartmentNameVo> nameVos = nameTree(departmentNameVos);
        return ResponseResult.okResult(nameVos);
    }


    /**
     * 根据ID查询部门
     *
     * @param id
     * @return
     */
    @Override
    public ResponseResult selectDepartmentById(Integer id) {
        Department department = departmentMapper.selectById(id);
        return ResponseResult.okResult(department);
    }

    /**
     * 添加部门
     *
     * @param departmentDto
     * @return
     */
    @Override
    public ResponseResult saveDepartment(DepartmentDto departmentDto) {
//        参数校验
        if (departmentDto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        if (departmentDto.getParentId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
//        上级部门校验
        Department department = departmentMapper.selectById(departmentDto.getParentId());
        if (department == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARENT_DEPARTMENT_NOT_FOUND);
        }
//        判断是否已经存在
        Department selectOne = departmentMapper.selectOne(
                new LambdaQueryWrapper<Department>()
                        .eq(Department::getDepartmentName, departmentDto.getDepartmentName()));
        if (selectOne != null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_EXIST);
        }
//        TODO 同名部门校验
//        添加部门
        Department dp = new Department();
        BeanUtils.copyProperties(departmentDto, dp);
        dp.setPid(departmentDto.getParentId());
        dp.setDepartmentLevel(department.getDepartmentLevel() + 1);
        dp.setCreatedTime(LocalDateTime.now());
        dp.setUpdatedTime(LocalDateTime.now());
        departmentMapper.insert(dp);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 修改部门
     *
     * @param departmentDto
     * @return
     */
    @Override
    public ResponseResult updateDepartment(DepartmentDto departmentDto) {
//        参数校验
        if (departmentDto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        Department parent = departmentMapper.selectById(departmentDto.getParentId());
        if (!parent.getDepartmentName().equals(departmentDto.getParentName())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARENT_DEPARTMENT_NOT_FOUND);
        }
        Department department = new Department();
        BeanUtils.copyProperties(departmentDto, department);
//        修改部门
        department.setUpdatedTime(LocalDateTime.now());
        department.setPid(departmentDto.getParentId());
        updateById(department);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 删除部门
     *
     * @param id
     * @return
     */
    @Override
    public ResponseResult deleteDepartment(Integer id) {
//        参数校验
        if (id == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        Department department = departmentMapper.selectById(id);
        if (department == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
//        将pid传给子级部门的pid   删除部门
        List<Department> departments = departmentMapper.selectList(
                new LambdaQueryWrapper<Department>()
                        .eq(Department::getPid, department.getId()));
//        将子部门所有的pid替换
        if (departments != null && departments.size() > 0) {
            departments.forEach(d -> d.setPid(department.getPid()));
        }
        departmentMapper.deleteById(id);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 部门名称列表树化
     *
     * @param departments
     * @return
     */
    private List<DepartmentNameVo> nameTree(List<DepartmentNameVo> departments) {
        Map<Integer, DepartmentNameVo> departmentMap = new HashMap<>(); // 使用部门ID作为键，方便查找和存储部门对象

// 第一次循环：将所有部门以部门ID为键存储到Map中
        for (DepartmentNameVo department : departments) {
            departmentMap.put(department.getId(), department);
        }

// 第二次循环：构建树状结构
        List<DepartmentNameVo> processedList = new ArrayList<>();
        for (DepartmentNameVo department : departments) {
            // 如果当前部门的父部门存在，则将当前部门添加到父部门的子部门列表中
            if (department.getPid() != null) {
                DepartmentNameVo parent = departmentMap.get(department.getPid());
                if (parent != null) {
                    if (parent.getDepartments() == null) {
                        parent.setDepartments(new ArrayList<>());
                    }
                    parent.getDepartments().add(department);
                }
            }
            // 如果当前部门的父部门不存在，则将其作为顶级部门
            else {
                processedList.add(department);
            }
        }
        return processedList;
    }

    /**
     * 分页结果树化
     *
     * @param departments
     */
    private List<DepartmentPageVo> tree(List<DepartmentPageVo> departments) {
        Map<Integer, DepartmentPageVo> departmentMap = new HashMap<>(); // 使用部门ID作为键，方便查找和存储部门对象

// 第一次循环：将所有部门以部门ID为键存储到Map中
        for (DepartmentPageVo department : departments) {
            departmentMap.put(department.getId(), department);
        }

// 第二次循环：构建树状结构
        List<DepartmentPageVo> processedList = new ArrayList<>();
        for (DepartmentPageVo department : departments) {
            // 如果当前部门的父部门存在，则将当前部门添加到父部门的子部门列表中
            if (department.getPid() != null) {
                DepartmentPageVo parent = departmentMap.get(department.getPid());
                if (parent != null) {
                    if (parent.getDepartments() == null) {
                        parent.setDepartments(new ArrayList<>());
                    }
                    parent.getDepartments().add(department);
                }
            }
            // 如果当前部门的父部门不存在，则将其作为顶级部门
            else {
                processedList.add(department);
            }
        }
        return processedList;
    }
}
